home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / amhelios / calcsub.cpp < prev    next >
C/C++ Source or Header  |  1999-01-01  |  6KB  |  297 lines

  1. /* -------------------------------------------------------------------------- *\
  2.    CALCSUB.CPP
  3.    Copyright © 1997 by Jarno van der Linden
  4.    jarno@kcbbs.gen.nz
  5.  
  6.    Calculation subtask for AmHelios.
  7.    Subtask handling taken from MUI Subtask.c example
  8.  
  9.    This program is Freeware, and all usual Freeware rules apply.
  10.  
  11.    24 Aug 1997: Project started
  12. \* -------------------------------------------------------------------------- */
  13.  
  14. /* -------------------------------- Includes -------------------------------- */
  15. #include "CalcSub.h"
  16.  
  17. #include <dos/dosextens.h>
  18. #include <dos/dostags.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22.  
  23. /* ------------------------------ Definitions ------------------------------- */
  24. #define STC_STARTUP  -2
  25. #define STC_SHUTDOWN -1
  26. #define STC_START 0
  27. #define STC_STOP  1
  28. #define STC_SUSPEND 2
  29. #define STC_RESUME  3
  30.  
  31. #define CALCSUB_SNAPSHOT 16
  32.  
  33. /* --------------------------------- Macros --------------------------------- */
  34.  
  35. /* -------------------------------- Typedefs -------------------------------- */
  36.  
  37. /* -------------------------------- Structs --------------------------------- */
  38.  
  39. /* ------------------------------ Proto Types ------------------------------- */
  40.  
  41. /* -------------------------------- Globals --------------------------------- */
  42.  
  43. /* ---------------------------------- Code ---------------------------------- */
  44. SubTask::SubTask(char *name)
  45. {
  46.     SpawnSubTask(name);
  47. }
  48.  
  49.  
  50. SubTask::~SubTask()
  51. {
  52.     KillSubTask();
  53. }
  54.  
  55.  
  56. void SubTask::Start()
  57. {
  58.     SendSubTaskMsg(STC_START,NULL);
  59. }
  60.  
  61.  
  62. void SubTask::Stop()
  63. {
  64.     SendSubTaskMsg(STC_STOP,NULL);
  65. }
  66.  
  67.  
  68. void SubTask::Suspend()
  69. {
  70.     SendSubTaskMsg(STC_SUSPEND,NULL);
  71. }
  72.  
  73.  
  74. void SubTask::Resume()
  75. {
  76.     SendSubTaskMsg(STC_RESUME,NULL);
  77. }
  78.  
  79.  
  80. LONG SubTask::SendSubTaskMsg(WORD command,APTR params)
  81. {
  82.     message.stm_Message.mn_ReplyPort = reply;
  83.     message.stm_Message.mn_Length    = sizeof(struct SubTaskMsg);
  84.     message.stm_Command              = command;
  85.     message.stm_Parameter            = params;
  86.     message.stm_Result               = 0;
  87.  
  88.     PutMsg(command==STC_STARTUP ? &((struct Process *)task)->pr_MsgPort : port,(struct Message *)&message);
  89.     WaitPort(reply);
  90.     GetMsg(reply);
  91.  
  92.     return(message.stm_Result);
  93. }
  94.  
  95.  
  96. void SubTask::SpawnSubTask(char *name)
  97. {
  98.     if (reply = CreateMsgPort())
  99.     {
  100.         if (task = (struct Task *)CreateNewProcTags(NP_Entry,Main,NP_Name,name,NP_Priority,-2,TAG_DONE))
  101.         {
  102.             if (SendSubTaskMsg(STC_STARTUP,this))
  103.             {
  104.                 return;
  105.             }
  106.         }
  107.         DeleteMsgPort(reply);
  108.     }
  109. }
  110.  
  111.  
  112. void SubTask::KillSubTask()
  113. {
  114.     SendSubTaskMsg(STC_SHUTDOWN,NULL);
  115.     DeleteMsgPort(reply);
  116. }
  117.  
  118.  
  119. /* the following functions are called from the sub task */
  120.  
  121. void SubTask::ExitSubTask(SubTask *thisst,struct SubTaskMsg *stm)
  122. {
  123.     /*
  124.     ** We reply after a Forbid() to make sure we're really gone
  125.     ** when the main task continues.
  126.     */
  127.  
  128.     if (thisst->port)
  129.         DeleteMsgPort(thisst->port);
  130.  
  131.     Forbid();
  132.     stm->stm_Result = FALSE;
  133.     ReplyMsg((struct Message *)stm);
  134. }
  135.  
  136. SubTask *SubTask::InitSubTask(void)
  137. {
  138.     struct Task *me = FindTask(NULL);
  139.     SubTask *thisst;
  140.     struct SubTaskMsg *stm;
  141.  
  142.     /*
  143.     ** Wait for our startup message from the SpawnSubTask() function.
  144.     */
  145.  
  146.     WaitPort(&((struct Process *)me)->pr_MsgPort);
  147.     stm  = (struct SubTaskMsg *)GetMsg(&((struct Process *)me)->pr_MsgPort);
  148.     thisst   = (SubTask *)stm->stm_Parameter;
  149.  
  150.     if (thisst->port = CreateMsgPort())
  151.     {
  152.         /*
  153.         ** Reply startup message, everything ok.
  154.         ** Note that if the initialization fails, the code falls
  155.         ** through and replies the startup message with a stm_Result
  156.         ** of 0 after a Forbid(). This tells SpawnSubTask() that the
  157.         ** sub task failed to run.
  158.         */
  159.  
  160.         stm->stm_Result = TRUE;
  161.         ReplyMsg((struct Message *)stm);
  162.         return(thisst);
  163.     }
  164.     else
  165.     {
  166.         ExitSubTask(thisst,stm);
  167.         return(NULL);
  168.     }
  169. }
  170.  
  171.  
  172. void __asm __saveds SubTask::Main(void)
  173. {
  174.     SubTask *thisst;
  175.  
  176.     if(thisst = InitSubTask())
  177.     {
  178.         BOOL running = TRUE;
  179.         BOOL worktodo = FALSE;
  180.         BOOL suspended = FALSE;
  181.         struct SubTaskMsg *stm;
  182.  
  183.         for(;;)
  184.         {
  185.             while(stm = (struct SubTaskMsg *)GetMsg(thisst->port))
  186.             {
  187.                 switch(stm->stm_Command)
  188.                 {
  189.                     case STC_SHUTDOWN:
  190.                         running = FALSE;
  191.                         break;
  192.                     case STC_START:
  193.                         worktodo = TRUE;
  194.                         thisst->StartFunc();
  195.                         break;
  196.                     case STC_STOP:
  197.                         worktodo = FALSE;
  198.                         thisst->StopFunc();
  199.                         break;
  200.                     case STC_SUSPEND:
  201.                         suspended = TRUE;
  202.                         break;
  203.                     case STC_RESUME:
  204.                         suspended = FALSE;
  205.                         break;
  206.                     default:
  207.                         stm->stm_Result = thisst->HandleMessage(stm->stm_Command,stm->stm_Parameter);
  208.                         break;
  209.                 }
  210.                 if(!running)
  211.                     break;
  212.  
  213.                 ReplyMsg((struct Message *)stm);
  214.             }
  215.             if(!running)
  216.                 break;
  217.  
  218.             if((worktodo) && (!suspended))
  219.             {
  220.                 worktodo = thisst->SubFunc();
  221.                 if(!worktodo)
  222.                     thisst->StopFunc();
  223.             }
  224.             else
  225.             {
  226.                 WaitPort(thisst->port);
  227.             }
  228.         }
  229.         if(worktodo)
  230.             thisst->StopFunc();
  231.  
  232.         ExitSubTask(thisst,stm);
  233.     }
  234. }
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241. CalcSub::CalcSub(char *name,RadEqnSolve *radiosity_arg,Environ *env_arg)
  242.     : SubTask(name)
  243. {
  244. #if (defined(_HEMI_CUBE) || defined(_CUBIC_TETRA))
  245.     radiosity = (ProgRad *)radiosity_arg;
  246. #elif defined(_RAY_CAST)
  247.     radiosity = (RayRad *)radiosity_arg;
  248. #else
  249.     radiosity = radiosity_arg;
  250. #endif
  251.  
  252.     env = env_arg;
  253. }
  254.  
  255.  
  256. void CalcSub::Snapshot()
  257. {
  258.     SendSubTaskMsg(CALCSUB_SNAPSHOT,NULL);
  259. }
  260.  
  261.  
  262. void CalcSub::StartFunc()
  263. {
  264.     radiosity->Open(env);
  265. }
  266.  
  267.  
  268. BOOL CalcSub::SubFunc()
  269. {
  270.     return !(radiosity->Calculate());
  271. }
  272.  
  273.  
  274. void CalcSub::StopFunc()
  275. {
  276.     radiosity->Close();
  277. }
  278.  
  279.  
  280. void CalcSub::SnapshotFunc()
  281. {
  282.     radiosity->Snapshot();
  283. }
  284.  
  285.  
  286. LONG CalcSub::HandleMessage(WORD command,APTR parameter)
  287. {
  288.     switch(command)
  289.     {
  290.         case CALCSUB_SNAPSHOT:
  291.             SnapshotFunc();
  292.             break;
  293.     }
  294.  
  295.     return 0;
  296. }
  297.